package ws

import (
	"github.com/gorilla/websocket"
	"go.uber.org/zap"
	"gobase/logger"
)

// Client 单个 websocket 信息
type Client struct {
	Id, Group   string
	StopConn    chan struct{}
	Socket      *websocket.Conn
	ReadMessage chan []byte
	SendMessage chan []byte
}

// MessageData 单个发送数据信息
type MessageData struct {
	Id, Group string
	Message   []byte
}

// GroupMessageData 组广播数据信息
type GroupMessageData struct {
	Group   string
	Message []byte
}

// BroadCastMessageData 广播发送数据信息
type BroadCastMessageData struct {
	Message []byte
}

// Read 读信息，从 websocket 连接直接读取数据
func (c *Client) Read() {
	defer func() {
		WebsocketManager.UnRegister <- c
		logger.Info("client disconnect", zap.String("id", c.Id))
		if err := c.Socket.Close(); err != nil {
			logger.Error("client disconnect error", zap.String("id", c.Id), zap.Error(err))
		}
	}()

	for {
		messageType, message, err := c.Socket.ReadMessage()
		if err != nil || messageType == websocket.CloseMessage {
			break
		}
		logger.Info("client receive message", zap.String("id", c.Id), zap.ByteString("message", message))
		c.ReadMessage <- message
	}
}

// Write 写信息，从 channel 变量 Send 中读取数据写入 websocket 连接
func (c *Client) Write() {
	defer func() {
		logger.Info("client disconnect", zap.String("id", c.Id))
		if err := c.Socket.Close(); err != nil {
			logger.Error("client disconnect error", zap.String("id", c.Id), zap.Error(err))
		}
	}()

	for {
		select {
		case message, ok := <-c.SendMessage:
			if !ok {
				_ = c.Socket.WriteMessage(websocket.CloseMessage, []byte{})
				return
			}
			logger.Info("client write message", zap.String("id", c.Id), zap.ByteString("message", message))
			err := c.Socket.WriteMessage(websocket.BinaryMessage, message)
			if err != nil {
				logger.Error("client write message error", zap.String("id", c.Id), zap.Error(err))
			}
		}
	}
}
